package com.gitee.zhziyun.cnfsystem.master;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.gitee.zhziyun.cnfsystem.model.FileAccept;
import com.gitee.zhziyun.cnfsystem.model.FileSource;
import com.gitee.zhziyun.cnfsystem.model.UserInfo;

import java.util.Map;

/**
 * 应用主控接口，用于管理系统核心功能，包括用户状态监听、消息处理、服务生命周期控制等。
 */
public interface AppMaster {
    /**
     * 用户状态监听器，用于监听用户上线和下线事件。
     */
    interface UserStatusListener {
        /**
         * 当某个用户上线时触发
         *
         * @param ip       上线用户的IP地址
         * @param userInfo 上线用户的详细信息
         */
        void userOnline(String ip, UserInfo userInfo);

        /**
         * 当某个用户下线时触发
         *
         * @param ip 下线用户的IP地址
         */
        void userOffline(String ip);
    }

    /**
     * 添加用户状态监听器
     *
     * @param listener 要添加的监听器
     */
    void addUserStatusListener(UserStatusListener listener);

    /**
     * 触发用户上线事件，通知所有注册的监听器
     *
     * @param ip       上线用户的IP地址
     * @param userInfo 上线用户的详细信息
     */
    void fireUserOnline(String ip, UserInfo userInfo);

    /**
     * 触发用户下线事件，通知所有注册的监听器
     *
     * @param ip 下线用户的IP地址
     */
    void fireUserOffline(String ip);

    /**
     * 消息监听器，用于接收来自其他节点的消息
     */
    interface MessageListener {
        /**
         * 收到消息时触发
         *
         * @param ip      发送方的IP地址
         * @param message 收到的消息内容
         */
        void onMessage(String ip, String message);

        /**
         * 收到文件消息时触发
         *
         * @param ip          发送方的IP地址
         * @param fileSource  文件信息
         */
        void onFileMessage(String ip, FileSource fileSource);

        /**
         * 收到文件接收确认时触发
         * @param  ip         发送方的IP地址
         * @param fileAccept  文件信息
         */
        void onFileAccept(String ip, FileAccept fileAccept);
    }

    /**
     * 添加消息监听器
     *
     * @param listener 要添加的消息监听器
     */
    void addMessageListener(MessageListener listener);

    /**
     * 通知所有注册的消息监听器收到新消息
     *
     * @param ip      消息发送方的IP地址
     * @param message 收到的消息内容
     */
    void fireMessage(String ip, String message);

    /**
     * 通知所有注册的消息监听器收到新文件
     *
     * @param ip         消息发送方的IP地址
     * @param fileSource 文件源信息
     */
    void fireFileMessage(String ip, FileSource fileSource);

    /**
     * 通知所有注册的消息监听器确认文件
     * @param ip         消息发送方的IP地址
     * @param fileAccept 文件源信息
     */
    void fireFileAccept(String ip, FileAccept fileAccept);

    interface MulticastListener {
        /**
         * 监听到多播消息
         *
         * @param ip      消息发送方的IP地址
         * @param message 收到的多播消息
         */
        void onMulticastMessage(String ip, String message);

        /**
         * 监听到多播文件
         * @param ip 文件发送方的IP地址
         * @param fileSource 文件源信息
         */
        void onMulticastFileMessage(String ip, FileSource fileSource);

        /**
         * 监听多播文件接收方确认
         * @param ip 文件接收方IP地址
         * @param fileAccept 文件接收信息
         */
        void onMulticastFileAccept(String ip, FileAccept fileAccept);
    }

    /**
     * 添加多播消息监听器
     *
     * @param listener 要添加的消息监听器
     */
    void addMulticastListener(MulticastListener listener);

    /**
     * 触发多播文件发送消息
     *
     * @param ip      消息发送方的IP地址
     * @param message 文件元信息
     */
    void fireMulticastMessage(String ip, String message);

    /**
     * 触发组播文件发送
     * @param ip         消息发送方的IP地址
     * @param fileSource 文件信息
     */
    void fireMulticastFileMessage(String ip, FileSource fileSource);

    /**
     * 触发多播文件接收消息
     * @param ip          消息发送方的IP地址
     * @param fileAccept  文件元信息
     */
    void fireMulticastFileAccept(String ip, FileAccept fileAccept);

    /**
     * 获取当前用户的信息
     *
     * @return 返回当前用户的UserInfo对象
     */
    UserInfo getUserInfo();

    /**
     * 获取主服务启动的时间戳
     *
     * @return 返回主服务启动的时间戳（毫秒）
     */
    long getStartTime();

    /**
     * 获取主服务当前运行状态
     *
     * @return 如果服务正在运行则返回true，否则返回false
     */
    boolean isRunning();

    /**
     * 获取当前在线用户列表
     *
     * @return 返回一个Map，键为IP地址，值为对应的UserInfo对象
     */
    Map<String, UserInfo> getIpUserMap();

    /**
     * 向指定的目标发送一条消息
     *
     * @param message     需要发送的消息内容
     * @param receiveIp   消息接收方的IP地址
     * @param receivePort 消息接收方的端口号
     * @throws JsonProcessingException 如果消息序列化失败则抛出此异常
     */
    void sendMessageToUser(String message, String receiveIp, int receivePort) throws JsonProcessingException;

    /**
     * 发送一条组播消息
     *
     * @param message     需要发送的消息内容
     * @throws JsonProcessingException 如果消息序列化失败则抛出此异常
     */
    void multicastMessage(String message) throws JsonProcessingException;

    /**
     * 发送文件给用户
     *
     * @param fileSource  需要发送的文件源
     * @param receiveIp   接收方IP地址
     * @param receivePort 接收方端口
     * @throws JsonProcessingException 如果消息序列化失败则抛出此异常
     */
    void sendFileToUser(FileSource fileSource, String receiveIp, int receivePort) throws JsonProcessingException;

    /**
     * 通知用户确认接收文件
     *
     * @param fileAccept  需要接收文件信息
     * @param receiveIp   接收方IP地址
     * @param receivePort 接收方端口
     * @throws JsonProcessingException 如果消息序列化失败则抛出此异常
     */
    void acceptFile(FileAccept fileAccept, String receiveIp, int receivePort) throws JsonProcessingException;

    void multicastFile(FileSource fileSource, String receiveIp, int receivePort) throws JsonProcessingException;

    void multicastAcceptFile(FileAccept fileAccept, String receiveIp, int receivePort) throws JsonProcessingException;

    /**
     * 启动主服务
     */
    void start();

    /**
     * 停止主服务
     */
    void stop();
}